#ifndef VIA_IMG_H__
#define VIA_IMG_H__

#include <windows.h>
#include <tchar.h>
#include <process.h>
#include <assert.h>

#define ALIGN4(w)	((((w)+3)>>2)<<2)

typedef BOOL (*VIAREADMEMORY_FUNC) (HANDLE h, PBYTE pDst, PBYTE pSrc, size_t size);

#define COLOR_FORMAT_NUM (8)

typedef enum ColorFormat {
	ColorFormat_BYTE = 0,
	ColorFormat_BGR,
	ColorFormat_RGB,
	ColorFormat_YUV,
	ColorFormat_WORD,
	ColorFormat_DWORD,
	ColorFormat_FLOAT,
	ColorFormat_DOUBLE
} ColorFormat;

namespace nVIA {
	class CBitmap;
}

class nVIA::CBitmap {
public:
	CBitmap() {
		m_buffer = NULL; 
		m_bufSize = 0; 
		m_bits = NULL;
		m_bitsSize = 0;

		reset();
	}
	CBitmap(int width, int height, ColorFormat format, BOOL align = TRUE) {
		m_buffer = NULL; 
		m_bufSize = 0;
		m_bits = NULL;
		m_bitsSize = 0;
		reset();
		Init(width, height, format, align);
	}
	~CBitmap() {Release();}

	BOOL	Init(int width, int height, ColorFormat format, BOOL align = TRUE);
	void	Release();

	int	Width() { return m_width; }
	int	Height()	{ return m_height; }
	int	BufferPitch()	{ return m_bufferPitch; }
	int Pitch() { return m_pitch; }
	BYTE*	Buffer() { return m_buffer; }
	BYTE*	Bits()	{ return m_bits; }
	BITMAPINFO*	Info() { return &m_biInfo; }
	BOOL	Update();
// 	void	SetWidth(int width) { m_width = width; }
// 	void	SetHeight(int height) { m_height = height; }
// 	void	SetPitch(int pitch) { m_bufferPitch = pitch; }
// 	void	SetBits(BYTE* bits) { m_buffer = bits; }
	//void	ReadBitsFrom(BYTE* bits);

public:
	static int	GetFormatNum() { return COLOR_FORMAT_NUM; }
	static TCHAR*	GetFormatNames(int i) { 
		if (i >= 0 && i < COLOR_FORMAT_NUM) 
			return m_formatNames[i]; 
		else
			return NULL;
	}

private:
	void	reset() {
		m_width = 0;
		m_height = 0;
		m_bufferPitch = 0;
		m_pitch = 0;
		m_isAlign = TRUE;
	}

	int		getBufferPitchFromFormat() {
		int pitch;
		switch (m_format) {
		case ColorFormat_BYTE:
			if (m_isAlign)
				pitch = ALIGN4(m_width * sizeof(char));
			else
				pitch = m_width * sizeof(char);
			break;
		case ColorFormat_WORD:
			if (m_isAlign)
				pitch = ALIGN4(m_width * sizeof(short));
			else
				pitch = m_width * sizeof(short);
			break;
		case ColorFormat_DWORD:
			if (m_isAlign)
				pitch = ALIGN4(m_width * sizeof(int));
			else
				pitch = m_width * sizeof(int);
			break;
		case ColorFormat_FLOAT:
			if (m_isAlign)
				pitch = ALIGN4(m_width * sizeof(float));
			else
				pitch = m_width * sizeof(float);
			break;
		case ColorFormat_DOUBLE:
			if (m_isAlign)
				pitch = ALIGN4(m_width * sizeof(double));
			else
				pitch = m_width * sizeof(double);
			break;
		case ColorFormat_BGR:
		case ColorFormat_RGB:
		case ColorFormat_YUV:
			if (m_isAlign)
				pitch = ALIGN4(m_width * 3 * sizeof(char));
			else
				pitch = m_width * 3 * sizeof(char);
			break;
		default:
			assert(0);
		}
		return pitch;
	}

protected:
	int	m_width;
	int	m_height;
	int m_pitch;
	int	m_bufferPitch;
	BYTE*	m_buffer;
	BYTE*	m_bits;
	int	m_bufSize;
	int m_bitsSize;
	BITMAPINFO	m_biInfo;
	BOOL	m_isAlign;
	ColorFormat m_format;
private:
	static	TCHAR*	m_formatNames[COLOR_FORMAT_NUM];
};

#endif//VIA_IMG_H__